import permissionRoutes from './module/main-routes'
import NProgress from "nprogress";
import store from "@/store";
import { isExternalLink, resolveRoutePath} from "@/utils";
import router from "@/route/index";
import { cloneDeep } from 'lodash';
import { nextTick } from 'vue'

/** 路由信息 */
export const generateRoute = (menus) => {
  return menus.map(menu => {
    const {
      parent, component, icon, path, title, i18n, id,
      extendRoute = false,
      children = [],
      hidden = false,
      keepAlive = true
    } = menu
    const currentMenu = {
      path,
      component,
      hidden,
      parent,
      extendRoute,
      meta: { key: id, title, i18n, icon, keepAlive },
      children: children.length === 0 ? [] : generateRoute(children),
      name: i18n
    }
    if (children.length <= 0) {
      delete currentMenu.children
    }
    return currentMenu
  })
}


/** 权限信息 */
export const generatePower = (powers) => powers.map(power => power.code)
// 将多层嵌套路由处理成平级
function flatAsyncRoutes(routes, breadcrumb = [], baseUrl = '') {
  let res = []
  routes.forEach(route => {
      if (route.children) {
          let childrenBaseUrl = ''
          if (baseUrl == '') {
              childrenBaseUrl = route.path
          } else if (route.path != '') {
              childrenBaseUrl = `${baseUrl}/${route.path}`
              // childrenBaseUrl = `${route.path}`
          }
          let childrenBreadcrumb = cloneDeep(breadcrumb)
          if (route.meta.breadcrumb !== false) {
              childrenBreadcrumb.push({
                  path: childrenBaseUrl,
                  title: route.meta.title,
                  hide: !route.meta.breadcrumb && route.meta.breadcrumb === false
              })
          }
          let tmpRoute = cloneDeep(route)
          tmpRoute.path = childrenBaseUrl
          tmpRoute.meta.breadcrumbNeste = childrenBreadcrumb
          delete tmpRoute.children
          res.push(tmpRoute)
          let childrenRoutes = flatAsyncRoutes(route.children, childrenBreadcrumb, childrenBaseUrl)
          childrenRoutes.map(item => {
              // 如果 path 一样则覆盖，因为子路由的 path 可能设置为空，导致和父路由一样，直接注册会提示路由重复
              if (res.some(v => v.path == item.path)) {
                  res.forEach((v, i) => {
                      if (v.path == item.path) {
                          res[i] = item
                      }
                  })
              } else {
                  res.push(item)
              }
          })
      } else {
          let tmpRoute = cloneDeep(route)
          if (baseUrl != '' && !isExternalLink(tmpRoute.path)) {
              if (tmpRoute.path != '') {
                  // tmpRoute.path = `${tmpRoute.path}`
                  tmpRoute.path = `${baseUrl}/${tmpRoute.path}`
              } else {
                  tmpRoute.path = baseUrl
              }
          }
          // 处理面包屑导航
          let tmpBreadcrumb = cloneDeep(breadcrumb)
          tmpBreadcrumb.push({
              path: tmpRoute.path,
              title: tmpRoute.meta.title,
              hide: !tmpRoute.meta.breadcrumb && tmpRoute.meta.breadcrumb === false
          })
          tmpRoute.meta.breadcrumbNeste = tmpBreadcrumb
          res.push(tmpRoute)
      }
  })
  return res
}
export const getHashRoutes = routes => {
  let _routes = []
  let childRoute = {}
  routes.map(item => {
    _routes.push(cloneDeep(item))
  })
  _routes.map((item, index) => {
    if (item.children) {
      childRoute[index] = 
        item.children = flatAsyncRoutes(item.children, [], item.path)
    }
  })
  return _routes
}
export const setUserRouteComponent = routes => {
  // console.log('routes: ', routes);
  /// 路由组件匹配
  routes.forEach(r => {
    // r.component = Number(r.parent) === 0
    //   ? permissionRoutes.Layout
    //   : r.children && r.children.length > 0 ? permissionRoutes.DefaultLayout : permissionRoutes[r.component]
    r.component = Number(r.parent) === 0
      ? permissionRoutes.Layout
      : permissionRoutes[r.component]

    if (r.children && r.children.length > 0) {
      setUserRouteComponent(r.children)
    }
  })
}

/**
 * 用户权限路由中是否包含当前访问路由的路径
 * @param routes
 * @param path
 * @returns {boolean}
 */
export const includeRoute = (routes, path) => {
  let hasRoute = false
  let myRoutes = cloneDeep(routes)
  for (let i = 0; i < myRoutes.length; i++) {
    const { path: itemPath, children = [] } = myRoutes[i]
    if (itemPath === path) {
      hasRoute = true
    } else {
      const isExistChild = children.length > 0
      if (isExistChild) {
        myRoutes[i].children.map(v => {
          v.path = `${itemPath}/${v.path}`
        })
        hasRoute = includeRoute(myRoutes[i].children, path)
      }
    }
    if (hasRoute) {
      break
    }
  }
  return hasRoute
}

const setDocumentTitle = title => {
  // 如有i18n在这里修改
  document.title = `SCRM - ${title}`
}

/**
 * 权限控制
 * @param to
 * @param from
 * @param next
 * @returns {Promise<void>}
 */
export const permissionController = async (to, from, next) => {
  NProgress.start();
  
  const { meta: { title = '' } } = to
  
  setDocumentTitle(title)
  
  // 取消未完成的请求
  await store.dispatch('app/execCancelToken')
  nextTick(() => {
    store.dispatch('user/addToFrom', { to, from })
  })
  // 是否登录
  if (!to.fullPath.includes('login') && !localStorage.getItem('token') && !localStorage.getItem('token_key')) {
    // 重定向 登录
    next({ path: '/login' })
  } else {
    // 如果基本路由中不包含页面前往的路径
    if (!router.getRoutes().map(it => it.path).includes(to.path)) {

      await store.dispatch('user/addRoute')
      await store.dispatch('user/addPower')
      // 路由判定
      const userRoutes = JSON.parse(JSON.stringify(store.getters.menu))
      const hasRoute = includeRoute(userRoutes, to.path)
      if (hasRoute) {
        // 注册路由
        const _routes = getHashRoutes(userRoutes)
        setUserRouteComponent(_routes)
        console.log('userRoutes: ', userRoutes);
        _routes.forEach(r => router.addRoute(r))
        // 目标跳转
        next({
          ...to
        })
      } else {
        // 重定向 404
        next('/error/404')
      }
    } else {
      // 放行
      next()
    }
  }
}
